package edu.bu.cs673.superkids123.test;

import static org.junit.Assert.*;

import java.util.List;
import java.util.Set;

import org.junit.Test;

import edu.bu.cs673.superkids123.children.model.resources.AchievementFactory;
import edu.bu.cs673.superkids123.common.DataObjectAccess.ChildManager;
import edu.bu.cs673.superkids123.common.model.Achievement;
import edu.bu.cs673.superkids123.common.model.AchievementRule;
import edu.bu.cs673.superkids123.common.model.AchievementRule.Activity;
import edu.bu.cs673.superkids123.common.model.AchievementRule.Compare;
import edu.bu.cs673.superkids123.common.model.AchievementRule.Metric;
import edu.bu.cs673.superkids123.common.model.Child;
import edu.bu.cs673.superkids123.common.model.Child.Sex;
import edu.bu.cs673.superkids123.parents.DataObjectAccess.AchievementManager;

public class SuperKids123Achievements {
	/**
	 * @author Abdelghani Bhalla
	 */

	@Test
	public void testAddingAchievement() {

		int id1 = -1;
		int id2 = -1;

		Achievement a1 = new Achievement("Level one achievement",
				"Big Ice Cream",
				"Child gets an ice cream when s/he passes level one");
		Achievement a2 = new Achievement("Level two achievement",
				"movie night",
				"Child goes to a movie night when s/he passes level two");

		id1 = AchievementManager.addAchievement(a1);
		id2 = AchievementManager.addAchievement(a2);

		assertTrue(id1 > -1 && id2 > -1);
	}

	@Test
	public void testAddingChildAchievements() {

		int userId;
		Child child = ChildManager.getChildByName("Susie");
		
		if (child == null) {
			Sex sex = Sex.Female;
			userId = ChildManager.addChild("Susie", 5, sex);			
			child = ChildManager.getChildById(userId);
		}
		
		Set<Achievement> earned = child.getAchievements();
		
		Achievement a1 = AchievementManager
				.getAchievementByName("Level one achievement");

		Achievement a2 = AchievementManager
				.getAchievementByName("Level two achievement");
		
		ChildManager.addChildAchievement(child, a1);
		ChildManager.addChildAchievement(child, a2);
		Set<Achievement> childAchievements = child.getAchievements();
		
		assertTrue(childAchievements.contains(a1) && childAchievements.contains(a2));
	}
	
	@Test
	public void testRemovingAchievement() {
		Achievement achievement = new Achievement("Test Achievement",
				"Test", "Description");
		int id = -1;
		id = AchievementManager.addAchievement(achievement);
		
		assertTrue(id > -1);
		
		AchievementManager.deleteAchievement(achievement);
		
		Achievement test = AchievementManager.getAchievementById(id);
		assertTrue(test == null);
	}

	@Test
	public void testAddAchievementWithRules() {
		
		Achievement a = new Achievement();
		a.setName("The 99 percent");
		a.setDescription("Finish a game with a 99 or better");
		a.setPoints(150);
		
		AchievementRule rule = new AchievementRule();
		rule.setMetric(Metric.Score);
		rule.setActivity(Activity.AllGames);
		rule.setComparer(Compare.GreaterThanOrEqual);
		rule.setValue(99);
		rule.setAchievement(a);
		
		a.getRules().add(rule);
		
		int id = -1;
		id = AchievementManager.addAchievement(a);
		
		assertTrue(id > -1);
		
		Achievement result = AchievementManager.getAchievementById(id);
		assertTrue(result.getRules().size() > 0);
	}
	
	@Test
	public void testImportFromXml() {
		AchievementFactory af = new AchievementFactory();
		List<Achievement> achievements = af.getAchievementsFromXML();
		assertTrue(achievements.size() > 0);
	}
	
	@Test
	public void testAwardAchievement() {
		// Get an achievement
		Achievement a = AchievementManager.getAchievementByName("The 99 percent");
		
		// Create 2 Children
		int userId1, userId2;
		Child child1 = ChildManager.getChildByName("Sara");
		Child child2 = ChildManager.getChildByName("Kenny");
		
		if (child1 == null) {
			Sex sex = Sex.Female;
			userId1 = ChildManager.addChild("Sara", 5, sex);			
			child1 = ChildManager.getChildById(userId1);
		}
		
		if (child2 == null) {
			Sex sex = Sex.Male;
			userId2 = ChildManager.addChild("Kenny", 2, sex);			
			child2 = ChildManager.getChildById(userId2);
		}
		
		// Add achievement to both
		if (child1.getAchievements().contains(a)) {
			child1.getAchievements().add(a);
			ChildManager.updateChild(child1);
		}
		
		if (child1.getAchievements().contains(a)) {
			child2.getAchievements().add(a);
			ChildManager.updateChild(child2);
		}
		
		// Get results
		Child result1 = ChildManager.getChildByName("Sara");
		Child result2 = ChildManager.getChildByName("Kenny");
		
		assertTrue(result1.getAchievements().contains(a) && result2.getAchievements().contains(a));
	}
}
